package org.invigorare.auctions.data;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import java.util.*;

import org.invigorare.MapUtils;

public class ProduceDataOpener extends SynchronizableInboundDataOpener {

	private static final int DATABASE_VERSION = 8;

	public static final String PRODUCE_TABLE_NAME 	= "produce_table";
	public static final String PRODUCE_TABLE_NULL_COL	= "nullIfNoData";	
	
	public static final String _ID				= "_id"; // Internal Android rowId: Column Name must be exactly so, for Query Adapters to work
	public static final String WEB_ID			= "webId"; // Web-Service rowId
	public static final String PRODUCE_NAME_EN	= "name_en"; // name in English 
	public static final String PRODUCE_NAME_HI	= "name_hi"; // name in Hindi

	public static final String LANGUAGE_CODE_ENGLISH = "EN";
	public static final String LANGUAGE_CODE_HINDI = "HI";
	private static final Map<String, String> languageCodeToNameCol = new HashMap<String, String>();
	
	private static final ColBinding[] columnBindings = new ColBinding[] {
		new ColBinding(_ID, 					SqlTypes.INT_KEY),
		new ColBinding(WEB_ID, 					SqlTypes.INT),
		
		new ColBinding(PRODUCE_NAME_EN, 		SqlTypes.TEXT),
		new ColBinding(PRODUCE_NAME_HI,			SqlTypes.TEXT)
	};
	
	public ProduceDataOpener(Context context) {
		super(context, PRODUCE_TABLE_NAME, null, DATABASE_VERSION, PRODUCE_TABLE_NULL_COL);
		setupLanguageCodeMap();
	}
	
	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL(createTableString(PRODUCE_TABLE_NAME, columnBindings));
		//populateFields(db); // comment out to test updating from webserver
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVer, int newVer) {
		// TODO right now, just discards the old db and makes a new one
		db.execSQL("DROP TABLE " + PRODUCE_TABLE_NAME);
		db.execSQL(createTableString(PRODUCE_TABLE_NAME, columnBindings));
	}
	
	public static SQLiteDatabase getWritableDb(Context context) {
		ProduceDataOpener dbHelper = new ProduceDataOpener(context);
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		return db;
	}
	
	public static SQLiteDatabase getReadableDb(Context context) {
		ProduceDataOpener dbHelper = new ProduceDataOpener(context);
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		return db;
	}

	/**
	 * Populates a new database with dummy fields.
	 */
	private void populateFields(SQLiteDatabase db) {
		for (String produceName : DummyProduceNames.PROD_NAMES) {
			ContentValues names = new ContentValues(2);
			names.put(PRODUCE_NAME_EN, produceName);
			names.put(PRODUCE_NAME_HI, produceName); // just write an English name for Hindi right now
			db.insert(PRODUCE_TABLE_NAME, PRODUCE_TABLE_NULL_COL, names);
		}
	}
	
	/** Opens the Produce Table from the database and returns 
	 * a Map of names of the produce types, in the language specified.
	 * 
	 * @param context the Application Context containing the desired database
	 * @param languageCode
	 * @return a map of the produce names from Name (string) to id (integer, as recorded by the web server).
	 */
	public static Map<String, Integer> getProduceNames(Context context, String languageCode) {
		Map<String, Integer> names = new HashMap<String, Integer>();
		
		SQLiteDatabase db = getReadableDb(context);
		Log.i("ProduceDataOpener", "Opening DB to get list of produce names.");
		
		// The Columns we want to fetch
		final String[] columns = {WEB_ID, nameColForLanguage(languageCode)};
		Log.i("ProduceDataOpener", "Language code requested: '" + languageCode + "' colName=" + nameColForLanguage(languageCode));
		final int ID_COL = 0;
		final int NAME_COL = 1;
		
		// Pull all the data and put it into the desired data structure
		Cursor query = db.query(PRODUCE_TABLE_NAME, columns, null, null, null, null, null);

		while (query.moveToNext()) {
			int id = query.getInt(ID_COL);
			String name = query.getString(NAME_COL);
			names.put(name, id);
		}
		
		// Cleanup and return
		Log.i("ProduceDataOpener", "Successfully got list of " + query.getCount() + " produce names.");
		query.close();
		db.close();
		return names;
	}
	
	private static void setupLanguageCodeMap() {
		if (languageCodeToNameCol.size() == 0) { // 0 size --> assume uninitialized
			languageCodeToNameCol.put(LANGUAGE_CODE_ENGLISH,	PRODUCE_NAME_EN);
			languageCodeToNameCol.put(LANGUAGE_CODE_HINDI, 		PRODUCE_NAME_HI);
		}
	}
	
	private static String nameColForLanguage(String languageCode) {
		setupLanguageCodeMap();
		return languageCodeToNameCol.get(languageCode.toUpperCase(Locale.US));
	}
	
	/**
	 * Returns a map of ProduceIds to Produce Names in the language specified.
	 * @param context
	 * @param languageCode
	 * @return
	 */
	public static Map<Integer, String> getProduceIds(Context context, String languageCode) {
		MapUtils<String,Integer> mapUtils = new MapUtils<String,Integer>();
		return mapUtils.invertedMap(getProduceNames(context, languageCode));
	}
}
